<script>
import {addRole, listRole, updateRole,getRoleCameraList} from "@/api/system/role";
import {roleMenuTreeselect} from "@/api/system/menu";
import log from "@/views/monitor/job/log.vue";

export default {
  name: "testRole",
  data() {
    return {
      roleList: [],
      total:0,
      loading:false,
      queryParams: {
        pageNum:1,
        pageSize:500
      },
      roleInfo:{},
      roleId:'',
      roleKey:'',
      roleName:'',
      roleMenuList:[],
      accessPermissionsList:[],
      form:{},
      rules:{
        roleName:[{ required: true, message: '请输入角色名称', trigger: 'blur' }],
        roleKey:[{ required: true, message: '请输入权限字符', trigger: 'blur' }],
        roleSort:[{required: true, message: '请输入角色顺序', trigger: 'blur'}]
      },
      open:false,
      cameraOptions :[],
      defaultProps: {
        children: "children",
        label: "name",
        value:"id"
      },
      defaultPropsRoles:{
        children: "children",
        label: "label",
        value:"id"
      },
    }
  },
  methods:{
    /** 获取角色列表*/
   async getList() {
      let res = await listRole(this.addDateRange(this.queryParams))
      this.roleList = res.rows
      this.total = res.total
      if(this.roleList.length > 0) {
        this.changeRoleId(this.roleList[0])
      }
    },
    /** 查询角色权限 */
   async changeRoleId(item){
      this.roleInfo = item
      this.roleId = item.roleId || ''
      const roleId = item.roleId || this.roleId
      await this.getRoleMenu(roleId)
      await this.getCameraTreeList(roleId)
    },
    /** 获取角色权限列表  */
   async getRoleMenu(roleId) {
      const roleMenu = await this.getRoleMenuTreeselect(roleId)
      let checkedKeys = roleMenu.checkedKeys
      checkedKeys.forEach(item=>{
        this.$nextTick(()=>{
          this.$refs.rolesTree.setChecked(item,true,false)
        })
      })
    },
    async getCameraTreeList(roleId){
      let res = await this.getRoleCameraTreeselect(roleId)
      let checkedKeys = res.data.cameraIdList
      checkedKeys.forEach(v=>{
        this.$nextTick(()=>{
          this.$refs.camera.setChecked(v,true,false)
        })
      })
    },

    getRoleCameraTreeselect(roleId) {
      return getRoleCameraList(roleId).then(response => {
        this.cameraOptions = response.data.areaCameraList
        return response
      })
    },

    markChecked(node, checkedKeys) {
      let hasCheckedDescendant = false;
      if (node.children && node.children.length) {
        node.children = node.children.map(child => {
          const checked = this.markChecked(child, checkedKeys);
          if (checked) hasCheckedDescendant = true;
          return child;
        });
      }
      node.checked = checkedKeys.includes(node.id) || hasCheckedDescendant;
      return node.checked;
    },

    /** 根据角色ID查询菜单树结构 */
   getRoleMenuTreeselect(roleId) {
      return roleMenuTreeselect(roleId).then(response => {
        const idsToMatch = ['100', '101', '102'];
        let filteredItems = response.menus[1].children.filter(item =>
          idsToMatch.some(id => item.id.toString().includes(id))
        );

        response.menus[1].children = filteredItems;
        this.roleMenuList = response.menus
        console.log(this.roleMenuList,'roleMenuList')
        return response
      })
    },

    async submitForm() {
      const menuIds = this.getMenuRolesAllCheckedKeys();
      const cameraIds = this.getMenuAllCheckedKeys();
      const valuesToAdd = [1, 36, 15];
      valuesToAdd.forEach(value => {
        if (!cameraIds.includes(value)) {
          cameraIds.push(value);
        }
      });

      // 排序菜单ID
      menuIds.sort((a, b) => a - b);
      // 提交角色信息
      let res = await updateRole({ ...this.roleInfo, menuIds, cameraIds });
      await this.getRoleMenu(this.roleId);
      await this.getCameraTreeList(this.roleId);

      if (res.code !== 200) {
        return this.$message.error(res.msg);
      }
      this.$message.success('保存成功');
    },

    /** 递归查询选中的菜单 */
    collectCheckedIds(node, idSet) {
      let hasChecked = false;

      // 递归遍历子节点
      if (node.children && node.children.length) {
        node.children.forEach(child => {
          const childChecked = this.collectCheckedIds(child, idSet);
          if (childChecked) hasChecked = true;
        });
      }

      // 如果当前节点被选中或有选中的子节点
      if (node.checked || hasChecked) {
        idSet.add(node.id); // 将当前节点的ID加入集合
      } else {
        idSet.delete(node.id); // 当前节点和所有子节点都未选中时，移除父节点ID
      }

      // 返回当前节点或子节点是否选中
      return node.checked || hasChecked;
    },

    /** 切换权限 */
    permissionChange(val) {
      this.$nextTick(() => {
        this.$set(val, 'checked', !val.checked)
        this.setChildrenChecked(val, val.checked);
      })
    },
    setChildrenChecked(node, checked) {
      if (node.children && node.children.length) {
        node.children.forEach(child => {
          this.$set(child, 'checked', checked);
          this.setChildrenChecked(child, checked);
        });
      }
    },
    /**新增角色*/
   async submitFormDialog(){
     let valid = await this.$refs.form.validate()
      if(!valid) return
      let obj = {
        ...this.form,
        deptCheckStrictly:true,
        deptIds:[],
        menuCheckStrictly:true,
        menuIds:[],
        status:'0'
      }
      let res = await addRole(obj)
      if(res.code !== 200) return  this.$message.error(res.msg)
      this.$message.success('保存成功')
      await this.getList()
      this.$refs.form.resetFields()
      this.open = false
    },
    cancel(){
      this.$refs.form.resetFields()
      this.open = false
    },
    handleAdd(){
      this.open = true
      this.$nextTick(()=>{
        this.$refs.form && this.$refs.form.clearValidate()
      })
    },
    getMenuAllCheckedKeys() {
      // 目前被选中的菜单节点
      let checkedKeys = this.$refs.camera.getCheckedKeys()
      // 半选中的菜单节点
      let halfCheckedKeys = this.$refs.camera.getHalfCheckedKeys()
      checkedKeys.unshift.apply(checkedKeys, halfCheckedKeys)
      return checkedKeys
    },
    getMenuRolesAllCheckedKeys() {
      // 目前被选中的菜单节点
      let checkedKeys = this.$refs.rolesTree.getCheckedKeys()
      // 半选中的菜单节点
      let halfCheckedKeys = this.$refs.rolesTree.getHalfCheckedKeys()
      checkedKeys.unshift.apply(checkedKeys, halfCheckedKeys)
      return checkedKeys
    },
  },
 async created() {
    await this.getList()
  }
}
</script>

<template>
 <div class="page-container">
  <div class="left">
    <div class="title">
      <span class="text">角色列表</span>
      <span class="iconRight" @click="handleAdd">
        <i class="el-icon-plus"></i>新增
      </span>
    </div>
    <div class="ul">
      <div :class="{'ac':item.roleId === roleId} " class="li" v-for="item in roleList" :key="item.roleId" @click="changeRoleId(item)">
        {{item.roleName}}
      </div>
    </div>
  </div>
   <div class="right">
     <div class="title">菜单权限</div>
     <el-tree
       class="tree-border"
       :data="roleMenuList"
       show-checkbox
       default-expand-all
       ref="rolesTree"
       node-key="id"
       empty-text="加载中，请稍候"
       :props="defaultPropsRoles"
     ></el-tree>
<!--     <el-table v-loading="loading" :data="roleMenuList" border style="margin-bottom: 30px">-->
<!--       <el-table-column label="所属模块" prop="label" width="120" />-->
<!--       <el-table-column label="归属权限">-->
<!--         <template v-slot="scope">-->
<!--             <div class="divCheck" >-->
<!--               <div class="item" v-for="item in scope.row.children" :key="item.id">-->
<!--                 <el-checkbox @change="permissionChange(item)"  :value="item.checked"></el-checkbox> <span style="margin-left: 8px">{{item.label}}</span>-->
<!--               </div>-->
<!--             </div>-->
<!--         </template>-->
<!--       </el-table-column>-->
<!--     </el-table>-->

     <div class="title">访问权限</div>
     <el-tree
       class="tree-border"
       :data="cameraOptions"
       show-checkbox
       default-expand-all
       ref="camera"
       node-key="id"
       empty-text="加载中，请稍候"
       :props="defaultProps"
     ></el-tree>

     <div class="df">
       <el-button type="primary" size="small" @click="submitForm">保存</el-button>
     </div>
   </div>

   <!-- 添加或修改角色配置对话框 -->
   <el-dialog title="添加角色" :visible.sync="open" width="500px" append-to-body :close-on-click-modal="false" :close-on-press-escape="false">
     <el-form ref="form" :model="form" :rules="rules" label-width="100px">
       <el-form-item label="角色名称" prop="roleName">
         <el-input v-model="form.roleName" placeholder="请输入角色名称" />
       </el-form-item>
       <el-form-item prop="roleKey">
          <span slot="label">
            <el-tooltip content="控制器中定义的权限字符，如：@PreAuthorize(`@ss.hasRole('admin')`)" placement="top">
              <i class="el-icon-question"></i>
            </el-tooltip>
            权限字符
          </span>
         <el-input v-model="form.roleKey" placeholder="请输入权限字符" />
       </el-form-item>
       <el-form-item label="角色顺序" prop="roleSort">
         <el-input-number style="width: 100%;" v-model="form.roleSort" controls-position="right" :min="0" />
       </el-form-item>
     </el-form>
    <div class="dialog_btn">
      <el-button size="small" style="width: 48%;" type="primary" @click="submitFormDialog">确 定</el-button>
      <el-button size="small" style="width: 48%;" @click="cancel">取 消</el-button>
    </div>
   </el-dialog>
 </div>
</template>

<style scoped lang="scss">
$--font-path: '~element-ui/lib/theme-chalk/fonts';
@import "~element-ui/packages/theme-chalk/src/index.scss";
@import  '@/assets/styles/customGlobal.scss';
.page-container{
  display: flex;
  justify-content: space-between;
}
.left{
  width: 200px;
  height: 100%;
  background: #fff;
  border-radius: 10px;
  padding: 16px;
  box-sizing: border-box;
  margin-right: 20px;
  cursor: pointer;
  .title{
    padding-bottom: 14px;
    display: flex;
    align-items: center;
    justify-content: space-between;
    border-bottom: 1px solid #F0F0F0;
    .text{
      font-family: Source Han Sans CN, Source Han Sans CN;
      font-weight: 500;
      font-size: 16px;
      color: #384A5C;
    }
    .iconRight{
      font-family: Source Han Sans CN, Source Han Sans CN;
      font-weight: 400;
      font-size: 14px;
      color: #0088FF;
    }
  }

  .ul{
    width: 100%;
    height: calc(100% - 40px);
    overflow-y: auto;
    margin-top: 14px;

    .li{
      padding-left: 10px;
      box-sizing: border-box;
      height: 36px;
      line-height: 36px;
      margin-bottom: 14px;
      background: #FFFFFF;
      border-radius: 4px 4px 4px 4px;
      font-family: Source Han Sans CN, Source Han Sans CN;
      font-weight: 400;
      font-size: 14px;
      color: #384A5C;
      &:last-child{
        margin-bottom: 0;
      }
      &.ac{
        background: rgba(0,136,255,0.1);
        color: #0088FF;
      }
    }

  }
}
.right{
  flex: 1;
  height: 100%;
  background: #fff;
  border-radius: 10px;
  padding: 16px;
  box-sizing: border-box;
  overflow-y: scroll;
  .title{
    font-family: Source Han Sans CN, Source Han Sans CN;
    font-weight: 500;
    font-size: 16px;
    color: #384A5C;
    margin-bottom: 14px;
  }
  .divCheck{
    display: flex;
    align-items: center;
    width: 100%;
    flex-wrap: wrap;
    .item{
      margin: 4px;
      background: rgba(0,136,255,0.1);
      border-radius: 4px 4px 4px 4px;
      padding: 4px 8px;
      box-sizing: border-box;
      font-family: Source Han Sans CN, Source Han Sans CN;
      font-weight: 400;
      font-size: 14px;
      color: #384A5C;
      display: flex;
      align-items: center;
    }
  }

}

</style>
